﻿using System;
using System.Reflection;
using System.Collections.Generic;

namespace SilverChart.Core.Configuration {
    public abstract class AbstractConfigurationItem : ConfigurationItem {
        protected AbstractConfigurationItem(ConfigurationParser parser) {
            Parser = parser;
        }

        public ConfigurationParser Parser { get; private set; }

        public T GetConfigurationValue<T>(string itemName) {

            return GetConfigurationValue<T>(itemName, default(T));
        }

        public T GetConfigurationValue<T>(string itemName, T defaultValue) {
            T value;
            if (TryGetConfigurationValue(itemName, out value)) {
                return value;
            }
            return defaultValue;
        }

        public virtual Boolean TryGetConfigurationValue<T>(string itemName, out T value) {
            if (itemName == null || itemName.Trim().Length <= 0) {
                throw new ArgumentException("itemName must not be null");
            }

            if (Parser == null) {
                value = default(T);
                return false;
            }

            return Parser.TryGetValue<T>(itemName, out value);
        }

        public virtual Boolean TryGetConfigurationValues<T>(string itemName, out IList<T> values) {
            if (itemName == null || itemName.Trim().Length <= 0) {
                throw new ArgumentException("itemName must not be null");
            }

            if (Parser == null) {
                values = null;
                return false;
            }

            return Parser.TryGetValues<T>(itemName, out values);
        }

        public static ConfigurationItem CreateInstance(Type type, ConfigurationParser parser) {
            ConfigurationItem configItem = null;
            ConstructorInfo ci = type.GetConstructor(new Type[] { typeof(ConfigurationParser) });
            if (ci != null) {
                configItem = (ConfigurationItem)ci.Invoke(new Object[] { parser });
            }

            ci = type.GetConstructor(new Type[] { });
            if (ci != null) {
                configItem = (ConfigurationItem)ci.Invoke(new Object[] { });
            }

            return configItem;
        }
    }
}
